package com.supergzt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.supergzt.constant.StatusConstants;
import com.supergzt.constant.ValidateMessageConstants;
import com.supergzt.context.SecurityContextHolder;
import com.supergzt.entity.base.LoginUser;
import com.supergzt.entity.dos.LoginLog;
import com.supergzt.entity.dos.User;
import com.supergzt.entity.vos.LoginVo;
import com.supergzt.entity.vos.RegisterVo;
import com.supergzt.entity.vos.UserPasswordVo;
import com.supergzt.exception.ServiceException;
import com.supergzt.service.LoginLogService;
import com.supergzt.service.RedissonService;
import com.supergzt.service.TokenService;
import com.supergzt.service.UserService;
import com.supergzt.mapper.UserMapper;
import com.supergzt.utils.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;

/**
* @author 张钧的电脑
* @description 针对表【user(用户)】的数据库操作Service实现
* @createDate 2023-03-30 09:11:39
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{

	@Resource
	private UserMapper userMapper;

	@Resource
	private LoginLogService loginLogService;

	@Resource
	private RedissonService redissonService;

	@Resource
	private TokenService tokenService;

	@Override
	public User getUserInfo() {
		return userMapper.selectById(SecurityContextHolder.getUserId());
	}

	@Override
	public void registerUser(RegisterVo registerVo) {
		Long phone = userMapper.selectCount(new QueryWrapper<User>().eq("phone", registerVo.getPhone()));
		if(phone > 0){
			throw new ServiceException(ValidateMessageConstants.REPEAT_PHONE);
		}
		Long email = userMapper.selectCount(new QueryWrapper<User>().eq("email", registerVo.getEmail()));
		if(email > 0){
			throw new ServiceException(ValidateMessageConstants.REPEAT_EMAIL);
		}
		userMapper.insert(new User().setPassword(SecurityUtils.encryptPassword(registerVo.getPassword())).setName(registerVo.getName()).setSex(registerVo.getSex()).setEmail(registerVo.getEmail()).setPhone(registerVo.getPhone()));
	}

	@Override
	public String login(LoginVo loginVo) {
		String account = loginVo.getAccount();
		//根据uuid获取验证码并删除该验证码缓存
		String code = redissonService.getStringAndDelete(KeyUtils.createCode(loginVo.getUuid()), String.class);
		//校验验证码
		AssertUtils.assertTrue(ValidateUtils.validateCode(loginVo.getCode(), code), new ServiceException(ValidateMessageConstants.WRONG_VERIFICATION_CODE));
		//根据账号(手机号或邮箱)查询用户
		User user = userMapper.getUserByAccount(account);
		//校验用户是否为空
		AssertUtils.assertTrue(StringUtils.isNotNull(user), new ServiceException(ValidateMessageConstants.WRONG_ACCOUNT));
		//校验用户是否已经删除
		AssertUtils.assertTrue(user.getIsDeleted().equals(StatusConstants.POSITIVE), new ServiceException(ValidateMessageConstants.DELETED_ACCOUNT));
		//校验密码
		AssertUtils.assertTrue(SecurityUtils.matchesPassword(loginVo.getPassword(), user.getPassword()), new ServiceException(ValidateMessageConstants.WRONG_PASSWORD));
		// 获取登录token
		LoginUser loginUser = new LoginUser().setUser(user).setLoginTime(System.currentTimeMillis());
		String token = tokenService.createToken(loginUser);
		loginUser.setToken(token);
		loginLogService.save(new LoginLog().setUserId(user.getUserId()).setLoginTime(LocalDateTime.now()));
		return token;
	}

	@Override
	public void logout(HttpServletRequest request) {
		tokenService.logout(request);
	}

	@Override
	public void updateUserPassword(UserPasswordVo userPasswordVo) {
		String password = SecurityContextHolder.getLoginUser().getUser().getPassword();
		if(!SecurityUtils.matchesPassword(userPasswordVo.getOldPassword(),password)){
			throw new ServiceException(ValidateMessageConstants.WRONG_OLD_PASSWORD);
		}
		update(new UpdateWrapper<User>().set("password",SecurityUtils.encryptPassword(userPasswordVo.getNewPassword())).eq("user_id",SecurityContextHolder.getUserId()));
	}

	@Override
	public void forceLogout() {
		tokenService.forceLogout(SecurityContextHolder.getUserId());
	}
}




